<script setup>
import api from '../api/favorites_api.js'
import userApi from '../api/user_api.js'
import attractionApi from '../api/attraction_api.js'
import {ref, onMounted, computed, watch} from "vue";
import { ElMessageBox } from "element-plus";
import lodash from 'lodash'
import * as echarts from 'echarts'

// 1. 数据定义区域
const tableData=ref([]);
const total=ref(0);
const editWinVisible=ref(false);
const attractionSelectVisible = ref(false); // 景点选择弹窗
const attractions = ref([]); // 景点列表
const searchObj = ref({
  current:1,
  limit:10,
  username:'',
  attractionname:''
});
// 图表相关
const chartVisible = ref(false);
const chartType = ref('bar'); // 图表类型: bar, pie, line
const chartRef = ref();

// 当前登录用户信息
const currentUserId = ref(localStorage.getItem("userId") || null);
const currentUserRole = ref(localStorage.getItem("role") || "user");

// 判断是否为管理员登录
const isAdminLogin = () => {
  return currentUserRole.value === 'admin';
};

// 用户和景点数据缓存
const userData = ref(new Map()); // 用户数据缓存
const attractionData = ref(new Map()); // 景点数据缓存

const obj=ref({});
const reseve=ref({});

// 计算属性：按景点统计收藏数量
const attractionStats = computed(() => {
  const stats = new Map();
  tableData.value.forEach(item => {
    const attractionName = item.attraction?.name || '未知景点';
    stats.set(attractionName, (stats.get(attractionName) || 0) + 1);
  });

  // 转换为数组并按数量排序
  return Array.from(stats.entries())
      .map(([name, count]) => ({ name, count }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 10); // 只取前10个
});

// 计算属性：按用户统计收藏数量
const userStats = computed(() => {
  const stats = new Map();
  tableData.value.forEach(item => {
    const username = item.user?.username || '未知用户';
    stats.set(username, (stats.get(username) || 0) + 1);
  });

  // 转换为数组并按数量排序
  return Array.from(stats.entries())
      .map(([name, count]) => ({ name, count }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 10); // 只取前10个
});

// 计算属性：收藏趋势（按首字母分类）
const categoryStats = computed(() => {
  const stats = new Map();
  tableData.value.forEach(item => {
    const attractionName = item.attraction?.name || '未知景点';
    const firstChar = attractionName.charAt(0);
    const category = /\w/.test(firstChar) ? '英文景点' : '中文景点';
    stats.set(category, (stats.get(category) || 0) + 1);
  });

  return Array.from(stats.entries())
      .map(([name, count]) => ({ name, value: count }));
});

const search=async ()=>{
  const result=await api.page({
    current: searchObj.value.current,
    limit: searchObj.value.limit
  });

  // 获取所有相关的用户和景点数据
  await loadRelatedData(result.data);

  // 前端过滤数据
  let filteredData = result.data;
  if (searchObj.value.username) {
    filteredData = filteredData.filter(item =>
      item.user && item.user.username &&
      item.user.username.toLowerCase().includes(searchObj.value.username.toLowerCase())
    );
  }
  if (searchObj.value.attractionname) {
    filteredData = filteredData.filter(item =>
      item.attraction && item.attraction.name &&
      item.attraction.name.toLowerCase().includes(searchObj.value.attractionname.toLowerCase())
    );
  }

  // 分页处理
  const start = (searchObj.value.current - 1) * searchObj.value.limit;
  const end = start + searchObj.value.limit;
  tableData.value = filteredData.slice(start, end);
  total.value = filteredData.length;
}

// 加载关联的用户和景点数据
const loadRelatedData = async (favoritesList) => {
  // 收集所有需要查询的user_id和attraction_id
  const userIds = [...new Set(favoritesList.map(item => item.user_id))].filter(id => id);
  const attractionIds = [...new Set(favoritesList.map(item => item.attraction_id))].filter(id => id);

  // 并行获取用户和景点数据
  const [usersResult, attractionsResult] = await Promise.all([
    userIds.length > 0 ? userApi.page({ current: 1, limit: 9999 }) : Promise.resolve({ data: [] }),
    attractionIds.length > 0 ? attractionApi.page({ current: 1, limit: 9999 }) : Promise.resolve({ data: [] })
  ]);

  // 构建用户数据映射
  if (usersResult && usersResult.data) {
    usersResult.data.forEach(user => {
      userData.value.set(user.id, user);
    });
  }

  // 构建景点数据映射
  if (attractionsResult && attractionsResult.data) {
    attractionsResult.data.forEach(attraction => {
      attractionData.value.set(attraction.id, attraction);
    });
  }

  // 为每个收藏项添加关联的用户和景点信息
  favoritesList.forEach(item => {
    item.user = userData.value.get(item.user_id) || { username: '未知用户' };
    item.attraction = attractionData.value.get(item.attraction_id) || { name: '未知景点' };
  });
}

// 获取所有景点用于选择
const loadAttractions = async () => {
  try {
    const result = await attractionApi.page({ current: 1, limit: 9999 });
    attractions.value = result.data || [];
  } catch (error) {
    console.error('获取景点列表失败:', error);
    ElMessageBox.alert('获取景点列表失败: ' + (error.message || '未知错误'), '提示', { type: 'error' });
  }
};

// 选择景点
const selectAttraction = (attraction) => {
  obj.value.attraction_id = attraction.id;
  obj.value.attraction_name = attraction.name; // 临时存储景点名称用于显示
  attractionSelectVisible.value = false;
};

// 取消选择景点
const cancelSelectAttraction = () => {
  attractionSelectVisible.value = false;
};

// 更新图表
const updateCharts = () => {
  if (!chartVisible.value) return;

  // 景点收藏统计图表
  const attractionChart = echarts.init(document.getElementById('attraction-chart'));
  let attractionOption;

  switch(chartType.value) {
    case 'line':
      attractionOption = {
        title: {
          text: '景点收藏趋势'
        },
        tooltip: {
          trigger: 'axis'
        },
        xAxis: {
          type: 'category',
          data: attractionStats.value.map(item => item.name)
        },
        yAxis: {
          type: 'value'
        },
        series: [{
          data: attractionStats.value.map(item => item.count),
          type: 'line',
          smooth: true,
          itemStyle: {
            color: '#409EFF'
          },
          areaStyle: {
            color: '#409EFF'
          }
        }]
      };
      break;

    default: // bar
      attractionOption = {
        title: {
          text: '景点收藏排行榜'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        xAxis: {
          type: 'category',
          data: attractionStats.value.map(item => item.name)
        },
        yAxis: {
          type: 'value'
        },
        series: [{
          type: 'bar',
          data: attractionStats.value.map(item => item.count),
          itemStyle: {
            color: '#409EFF'
          }
        }]
      };
  }

  attractionChart.setOption(attractionOption, true);

  // 用户收藏统计图表
  const userChart = echarts.init(document.getElementById('user-chart'));
  let userOption;

  switch(chartType.value) {
    case 'line':
      userOption = {
        title: {
          text: '用户收藏趋势'
        },
        tooltip: {
          trigger: 'axis'
        },
        xAxis: {
          type: 'category',
          data: userStats.value.map(item => item.name)
        },
        yAxis: {
          type: 'value'
        },
        series: [{
          data: userStats.value.map(item => item.count),
          type: 'line',
          smooth: true,
          itemStyle: {
            color: '#67C23A'
          },
          areaStyle: {
            color: '#67C23A'
          }
        }]
      };
      break;

    default: // bar
      userOption = {
        title: {
          text: '用户收藏排行榜'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        xAxis: {
          type: 'category',
          data: userStats.value.map(item => item.name)
        },
        yAxis: {
          type: 'value'
        },
        series: [{
          type: 'bar',
          data: userStats.value.map(item => item.count),
          itemStyle: {
            color: '#67C23A'
          }
        }]
      };
  }

  userChart.setOption(userOption, true);
};

// 切换图表类型
const switchChartType = (type) => {
  chartType.value = type;
  setTimeout(() => {
    updateCharts();
  }, 100);
};

// 显示图表
const showCharts = () => {
  chartVisible.value = true;
  setTimeout(() => {
    updateCharts();
  }, 100);
};

// 隐藏图表
const hideCharts = () => {
  chartVisible.value = false;
};

// 监听数据变化，自动更新图表
watch([tableData, chartType], () => {
  if (chartVisible.value) {
    updateCharts();
  }
});

onMounted(async ()=>{
  await search();
})

const editCancel=()=>{
  obj.value={};
  editWinVisible.value=false;
}

const editCommit=async ()=>{
  if(obj.value.id){
    await api.edit(obj.value);
  }
  else{
    // 新增收藏时确保数据完整
    const favoriteData = {
      user_id: obj.value.user_id || currentUserId.value,
      attraction_id: obj.value.attraction_id
    };
    await api.add(favoriteData);
  }
  search();
  editWinVisible.value=false;
}

const handleSearch=()=>{
  searchObj.value.current=1;
  search();
}

const handleSizeChange=(val)=>{
  searchObj.value.limit=val;
  search();
}

const handleCurrentChange=(val)=>{
  searchObj.value.current=val;
  search();
}

const handleAdd=()=>{
  obj.value={
    user_id: currentUserId.value,
    attraction_id: '',
    attraction_name: ''
  };

  // 普通用户只能收藏自己的，管理员可以指定用户
  if (!isAdminLogin()) {
    obj.value.user_id = currentUserId.value;
  }

  editWinVisible.value = true;
}

const handleEdit=(index,row)=>{
  obj.value=lodash.clone(row);
  // 添加景点名称用于显示
  if (row.attraction) {
    obj.value.attraction_name = row.attraction.name;
  }
  editWinVisible.value=true;
}

const handleDelete=(index,row)=>{
  ElMessageBox.confirm(
      '确认删除该收藏吗？',
      '删除提示',
      {
        confirmButtonText: '删除',
        cancelButtonText: '取消',
        type: 'error',
      }
  )
      .then(async () => {
        await api.del(row.id);
        searchObj.value.current=1;
        search();
      })
      .catch(() => {});
}
</script>
<template>
  <div class="favorites-management-container">
    <!-- 查询表单 -->
    <el-form :inline="true" :model="searchObj" class="demo-form-inline" style="margin-top: 10px; margin-bottom: 15px;">
      <el-form-item label="用户名">
        <el-input v-model="searchObj.username" placeholder="请输入用户名" clearable style="width: 200px;" />
      </el-form-item>
      <el-form-item label="景点名">
        <el-input v-model="searchObj.attractionname" placeholder="请输入景点名称" clearable style="width: 250px;" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleSearch">查询</el-button>
      </el-form-item>
      <el-form-item v-if="!isAdminLogin()">
        <el-button type="primary" @click="handleAdd">新增</el-button>
      </el-form-item>
      <el-form-item>
        <el-button v-if="!chartVisible" type="info" @click="showCharts">显示统计</el-button>
        <el-button v-else type="info" @click="hideCharts">隐藏统计</el-button>
      </el-form-item>
    </el-form>

    <!-- 图表区域 -->
    <div v-if="chartVisible" class="chart-container">
      <!-- 图表类型切换 -->
      <div class="chart-controls">
        <el-button :type="chartType === 'bar' ? 'primary' : 'default'" @click="switchChartType('bar')">柱状图</el-button>
        <el-button :type="chartType === 'line' ? 'primary' : 'default'" @click="switchChartType('line')">折线图</el-button>
      </div>

      <el-row :gutter="20">
        <el-col :span="12">
          <div id="attraction-chart" style="width: 100%; height: 400px;"></div>
        </el-col>
        <el-col :span="12">
          <div id="user-chart" style="width: 100%; height: 400px;"></div>
        </el-col>
      </el-row>
    </div>

    <!-- 用户表格 -->
    <div class="table-container">
      <el-table
          :data="tableData"
          style="width: 100%; margin-bottom: 20px;"
          border
          stripe
          :header-cell-style="{ 'background-color': '#f5f7fa', 'font-weight': 'bold' }"
      >
        <el-table-column label="用户" min-width="150">
          <template #default="scope">
            <div style="display: flex; align-items: center; padding-left: 10px;">
              {{ scope.row.user?.username || '未知用户' }}
            </div>
          </template>
        </el-table-column>
        <el-table-column label="景点" min-width="200">
          <template #default="scope">
            <el-popover effect="light" trigger="hover" placement="top" width="auto">
              <template #default>
                <div>景点名称: {{ scope.row.attraction?.name || '未知景点' }}</div>
                <div>景点ID: {{ scope.row.attraction_id }}</div>
                <div>用户: {{ scope.row.user?.username || '未知用户' }}</div>
                <div>用户ID: {{ scope.row.user_id }}</div>
              </template>
              <template #reference>
                <el-tag>{{ scope.row.attraction?.name || '未知景点' }}</el-tag>
              </template>
            </el-popover>
          </template>
        </el-table-column>
        <el-table-column label="操作" min-width="180" align="center">
          <template #default="scope">
  <!--          <el-button size="small" @click="handleEdit(scope.$index, scope.row)">-->
  <!--            编辑-->
  <!--          </el-button>-->
            <el-button
                size="small"
                type="danger"
                @click="handleDelete(scope.$index, scope.row)"
                style="margin-left: 5px;"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <el-pagination
        v-model:current-page="searchObj.current"
        v-model:page-size="searchObj.limit"
        :page-sizes="[10, 20, 30, 50]"
        background
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        style="text-align: right; margin-top: 10px;"
        />

    <!-- 编辑/新增对话框 -->
    <el-dialog v-model="editWinVisible" :title="obj.id ? '编辑收藏信息' : '新增收藏信息'" width="500px">
      <el-form :model="obj" label-width="100px">
        <el-form-item label="ID" v-if="obj.id">
          <el-input v-model="obj.id" autocomplete="off" disabled />
          <div class="el-form-item__help">ID为系统自动生成，不可修改</div>
        </el-form-item>
        <el-form-item label="当前用户" v-if="!isAdminLogin()">
          <el-input :value="currentUserId" autocomplete="off" disabled />
        </el-form-item>
        <el-form-item label="用户ID" v-if="isAdminLogin() && !obj.id">
          <el-input v-model="obj.user_id" autocomplete="off" placeholder="请输入用户ID" />
        </el-form-item>
        <el-form-item label="景点">
          <el-input
            v-model="obj.attraction_name"
            autocomplete="off"
            disabled
            v-if="obj.attraction_name"
          />

          <div v-if="!obj.attraction_name && obj.id">{{ obj.attraction?.name || '未知景点' }}</div>
          <div style="margin-top: 10px;">
            <el-button type="primary" @click="loadAttractions().then(() => attractionSelectVisible = true)">
              {{ obj.attraction_id ? '重新选择景点' : '选择景点' }}
            </el-button>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="editCancel">取消</el-button>
          <el-button type="primary" @click="editCommit" :disabled="!obj.attraction_id">
            {{ obj.id ? '更新' : '提交' }}
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 景点选择对话框 -->
    <el-dialog v-model="attractionSelectVisible" title="选择景点" width="800px">
      <el-table :data="attractions" height="400" @row-click="selectAttraction" style="width: 100%">
        <el-table-column prop="id" label="ID" width="80"></el-table-column>
        <el-table-column prop="name" label="景点名称" min-width="150"></el-table-column>
        <el-table-column prop="city" label="城市" min-width="120"></el-table-column>
        <el-table-column prop="type" label="类型" min-width="120"></el-table-column>
      </el-table>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancelSelectAttraction">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.chart-container {
  margin-bottom: 20px;
  padding: 20px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.chart-controls {
  margin-bottom: 20px;
  text-align: center;
}

.table-container {
  display: flex;
  justify-content: center;
}
</style>
